#ifndef TCP_SERVER_TIMERQUEUE_H
#define TCP_SERVER_TIMERQUEUE_H

#include "../../base/noncopyable.h"
#include "../tcp/Channel.h"
#include "../../base/Timestamp.h"

#include <set>
#include <vector>
#include <functional>

class TimerId;
class Timer;
class EventLoop;

typedef std::function<void()> TimerCallback;

class TimerQueue : muduo::noncopyable {
public:
    /**
     * 构造函数, 将时间事件绑定事件循环
     * @param loop
     */
    explicit TimerQueue(EventLoop *loop);

    ~TimerQueue();

    /**
     * 添加事件事件
     * @param cb 回调函数
     * @param when 何时调用
     * @param interval 调用间隔
     * @return 返回一个标识
     */
    TimerId addTimer(TimerCallback cb, Timestamp when, double interval);

    /**
     * 通过标识符取消对应的时间事件
     * @param timerId 对应的时间时间标识符
     */
    void cancel(TimerId timerId);

private:
    typedef std::pair<Timestamp, Timer *> Entry;
    typedef std::set<Entry> TimerList;
    typedef std::pair<Timer *, int64_t> ActiveTimer;
    typedef std::set<ActiveTimer> ActiveTimerSet;

    void addTimerInLoop(Timer *timer);

    void cancelInLoop(TimerId timerId);

    void handleRead();

    /**
     * 获取已过期的时间事件的集合
     */
    std::vector<Entry> getExpired(Timestamp now);

    /**
     * @param expired
     * @param now
     */
    void reset(const std::vector<Entry> &expired, Timestamp now);

    /**
     * 添加对应的时间事件, 返回是否成功
     * @param timer
     * @return
     */
    bool insert(Timer *timer);

    EventLoop *loop_;
    const int timerfd_;
    Channel timerfdChannel_;
    // 定时器的文件描述符channel
    TimerList timers_;

    bool callingExpiredTimers_;
    ActiveTimerSet activeTimers_;
    ActiveTimerSet cancelingTimers_;
};


#endif //TCP_SERVER_TIMERQUEUE_H
